package com.fmatos.carcontrol.bluetooth;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.LinkedList;
import java.util.concurrent.ConcurrentLinkedQueue;

import android.bluetooth.BluetoothSocket;
import android.util.Log;

/**
 * Reads connection asynchronously, as suggested in google API guide
 * http://developer.android.com/guide/topics/connectivity/bluetooth.html
 * @author fmatos
 *
 */
class ConnectedThread extends Thread {
 
	private static final String TAG = ConnectedThread.class.getSimpleName();

	private static final String TOKEN = "\n";
	
	private final BluetoothSocket mmSocket;
    private final InputStream mmInStream;
    private final OutputStream mmOutStream;
    
    private ConcurrentLinkedQueue<String> messageList;

 
    public ConnectedThread(BluetoothSocket socket) {
        mmSocket = socket;
        InputStream tmpIn = null;
        OutputStream tmpOut = null;
 
        // Get the input and output streams, using temp objects because
        // member streams are final
        try {
            tmpIn = socket.getInputStream();
            tmpOut = socket.getOutputStream();
        } catch (IOException e) {
        	
        }
 
        mmInStream = tmpIn;
        mmOutStream = tmpOut;
        messageList = new ConcurrentLinkedQueue<String>();
        
    }
 
    public void run() {
        byte[] buffer = new byte[1024];  // buffer store for the stream
        int bytes; // bytes returned from read()
 
     // holds temporary values, assembling them and putting them on queue when ready
        StringBuffer draftMessage = new StringBuffer(); 
        Log.i(TAG,"Thread starting");

        while (mmSocket.isConnected()) {
            try {
                bytes = mmInStream.read(buffer);
                draftMessage.append(new String(buffer,0,bytes));
                draftMessage = handleBuffer(draftMessage);
                
            } catch (IOException e) {
                break;
            }
        }
        
        Log.i(TAG,"Thread stopping");
    }
 
    /**
     * Looks for TOKENS in buffer, splitting messages and adding to the queue
     * @param draft
     * @return empty or partially filled buffer (it will never contain a token)
     */
    private StringBuffer handleBuffer(StringBuffer draftMessage) {
    	
    	int index = draftMessage.indexOf(TOKEN);
    	
        if ( index != -1 )  {        	
        	String message = draftMessage.substring(0, index);
        	messageList.add(message);
        	Log.i(TAG,"read: " + message);
        	
        	if ( message.length() == draftMessage.length() ) {
        		draftMessage = new StringBuffer();
        	} else {
        		StringBuffer tmp = draftMessage;
        		draftMessage = new StringBuffer();
        		draftMessage.append(tmp.substring(index+1));
        		// TODO this should be recursive
        		
        	}
        }
        
        return draftMessage;
	}

	/**
     * Call this from the main activity to send data to the remote device.
     * If message doesn't contain any token it is added to the end.
     * 
     */
        
     
    public void write(String message) {
        try {
        	if ( message.indexOf(TOKEN) == -1 ) {
        		message += TOKEN;
        	}
        	byte[] bytes = message.getBytes();
            mmOutStream.write(bytes);
        } catch (IOException e) { 
        	
        }
    }

    public String getMessage() {
    	if ( messageList != null ) {
    		return messageList.poll();
    	}
    	
    	return null;
    }
}